#!/usr/bin/env python
#
# wiki_parse does basic parsing on a wiki page, to determine links.
#
# This is a submodule of warbler (warbler.org)
#
# Copyright (c) 2008 by Patrick Maupin <pmaupin@gmail.com>

import re

def splitter():
    LeftBracket = '\\['
    RightBracket = '\\]'
    Space = ' '
    Tab = '\t'
    NL = '\n'

    def join(*what):
        return ''.join(what)

    def precededby(what):
        return join('(?<=', what, ')')

    def followedby(what):
        return join('(?=', what, ')')

    def or_(*what):
        return '|'.join(what)

    def set_(*what):
        return '[%s]' % ''.join(what)

    def group(*what):
        return '(%s)' % or_(*what)

    def oneormore(what, greedy=True):
        return what + '+' + (not greedy and '?' or '')

    def zeroormore(what, greedy=True):
        return what + '*' + (not greedy and '?' or '')

    def zeroorone(what, greedy=True):
        return what + '*' + (not greedy and '?' or '')

    code = join('{{{', zeroormore('.', False), '}}}')

    uppercase = 'A-Z'
    lowercase = 'a-z'
    digits = '0-9'
    whitespace = join(Space, Tab, NL)

    delimiter = set_('^_/', digits, lowercase, uppercase)
    camelcase = join(
                    set_(uppercase), oneormore(set_(lowercase)),
                    set_(uppercase), oneormore(set_(lowercase)),
                    zeroormore(set_(join(uppercase, lowercase))),
                    )
    ref1 = join(
                   LeftBracket,
                   camelcase,
                   oneormore(set_(whitespace)),
                   zeroormore(set_('^', LeftBracket, RightBracket)),
                   RightBracket,
               )

    ref2      = join(
                    precededby(delimiter),
                    camelcase,
                    followedby(delimiter),
                    )

    regexp = group(ref1, ref2, code)
    return re.compile(regexp, re.MULTILINE).split

splitter = splitter()

class RefString(str):
    pass


def splitstring(source):
    for s in splitter(source):
        if not s:
            continue
        if s.isalpha():
            result = RefString(s)
            result.name = s
            result.target = s
            s = result
        elif s.startswith('[') and s.endswith(']'):
            result = RefString(s)
            target = s.split()[0]
            name = s[len(target):-1]
            result.name = name
            result.target = target[1:]
            s = result
        yield s
